import java.util.ArrayList;
import org.newdawn.slick.*;
import org.newdawn.slick.util.FontUtils;
import org.newdawn.slick.command.*;

/**
 * Write a description of class MainMenuController here.
 * 
 * @author (your name) 
 * @version (a version number or a date)
 */
public class MainMenuController
{
    private static ArrayList<MenuBase> menuRenderList = new ArrayList<MenuBase>();
    private static ArrayList<MenuBase> menuStack = new ArrayList<MenuBase>();
    private static ArrayList<MenuBase> menuList = new ArrayList<MenuBase>();

    /**
     * Initializes the MainMenuController
     * @pre None
     * @param None
     * @return Void
     * @post MainMenuController is initialized.
     */
    public static void initialize(GameContainer gameContainer)
    {
        setMenu(registerMenu(new MainMenu()));
    } //End initialize method

    /**
     * The update method. Called each step from the GameContainer.
     * This is where all game logic will be performed for each GameObject.
     * Overloaded from the BasicGame class.
     * 
     * @pre GameContainer must be created
     * @param gameContainer The GameContainer
     * @param intDelta The delta time since the last step
     * @return void
     * @post Resources have been loaded
     */
    public static void update(GameContainer gameContainer, int intDelta) throws SlickException
    {
        for(MenuBase menuBase : menuStack)
        {
            menuBase.update(gameContainer, intDelta);
        } //End for-each loop
    } //End update method

    /**
     * The render method. Called each frame from the GameContainer.
     * This is where all game graphics will be drawn to the screen.
     * Overloaded from the BasicGame class.
     * 
     * @pre GameContainer must be created
     * @param gameContainer The GameContainer
     * @param graphics The graphics class used to draw to the screen
     * @return void
     * @post Resources have been loaded
     */
    public static void render(GameContainer gameContainer, Graphics graphics) throws SlickException
    {
        for(MenuBase menuBase : menuRenderList)
        {
            menuBase.render(gameContainer, graphics);
        } //End for-each loop
    } //End render method

    /**
     * Overrided method from InputProviderListener interface
     */
    public static void controlPressed(Keys key)
    {
        getCurrentMenu().controlPressed(key);
    } //End controlPressed method

    /**
     * Overrided method from InputProviderListener interface
     */
    public static void controlReleased(Keys key)
    {

    } //End controlReleased method

    /**
     * Registers the MenuBase instance for use.
     * 
     * @pre None
     * @param menu The MenuBase instance to register
     * @return The ID of the menu after it has registered.
     * @post The MenuBase instance has been added to menuList
     */
    public static int registerMenu(MenuBase menu)
    {
        int intIndex = menuList.size();
        menuList.add(menu);
        return intIndex;
    } //End registerMenu method

    /**
     * Sets the current menu to the menu with the given ID.
     * 
     * @pre None
     * @param menuID The ID of the menu to set as the current menu.
     * @return Void
     * @post The current menu has changed
     */
    public static void setMenu(int menuID)
    {
        if(menuID >= 0 && menuID < menuList.size())
        {
            if(menuStack.size() > 0)
            {
                getCurrentMenu().onUnset();
            } //End if
            
            menuStack.add(getMenu(menuID));
            getCurrentMenu().onSet();
            addToRenderList(getCurrentMenu());
        } //End if
    } //End setMenu method

    /**
     * Returns to the previous menu.
     * 
     * @pre None
     * @param None
     * @return Void
     * @post The current menu has changed
     */
    public static void previousMenu()
    {
        getCurrentMenu().onUnset();
        menuStack.remove(getCurrentMenu());
        getCurrentMenu().onSet();
        addToRenderList(getCurrentMenu());
    } //End previousMenu method

    /**
     * Returns the menu with the given menuID.
     * 
     * @pre The menu with the given ID must exist
     * @param menuID The ID of the menu
     * @return The menu with the given ID
     * @post None
     */
    public static MenuBase getMenu(int menuID)
    {
        return menuList.get(menuID);
    } //End getMenu method

    /**
     * Adds the menu to the render list.
     * Any menu in the render list will be rendered to the screen. It allows for transitional effects.
     * 
     * @pre None
     * @param menuBase The menu to add to the render list.
     * @return void
     * @post The menu has been added to the render list.
     */
    public static void addToRenderList(MenuBase menuBase)
    {
        if(!menuRenderList.contains(menuBase))
        {
            menuRenderList.add(menuBase);
        } //End if
    } //End addMenuToRenderList method

    /**
     * Removes the menu from the render list.
     * Any menu in the render list will be rendered to the screen. It allows for transitional effects.
     * 
     * @pre None
     * @param menuBase The menu to remove from the render list.
     * @return void
     * @post The menu has been removed from the render list.
     */
    public static void removeFromRenderList(MenuBase menuBase)
    {
        menuRenderList.remove(menuBase);
    } //End removeMenuFromMenuBase method

    /**
     * Returns the current active menu.
     * @pre None
     * @param None
     * @return The current menu
     * @post None
     */
    public static MenuBase getCurrentMenu()
    {
        if(menuStack.size() > 0)
        {
            return menuStack.get(menuStack.size() - 1);
        } //End if

        return null;
    } //End getCurrentMenu method
} //End class definition
